/**
 * Copyright (C), 2020-2021 by colley.ma
 * File Name: RateLimitVo.java
 * Encoding: UTF-8
 * Date: 2021年3月25日 下午3:44:40
 * History:
 */
package com.swak.frame.ratelimit.config;

import org.apache.commons.lang3.ArrayUtils;

import com.swak.frame.dto.base.DTO;
import com.swak.frame.ratelimit.annotation.RateLimit;
import com.swak.frame.ratelimit.event.RateAlarmEvent;

public class LimitCommand implements DTO {
    private static final long serialVersionUID = -8663031715419784133L;

    private String name;
    // 限流qps
    private int qps;

    private int capacity;

    private int instances;

    private boolean dynamic;

    // 是否开启限流
    private boolean enable;

    private Class<? extends RateAlarmEvent> event;

    public LimitCommand() {}

    public LimitCommand(boolean enable) {
        this.enable = enable;
    }

    public static LimitCommand newLimitCommand(LimitOperation limitResource) {
        LimitCommand.Builder builder = new LimitCommand.Builder();
        builder.capacity(limitResource.getCapacity()).qps(limitResource.getQps())
            .enable(limitResource.isEnable()).dynamic(limitResource.isDynamic())
            .instances(limitResource.getInstances()).name(limitResource.getName());
        RateLimit rateLimit = limitResource.getRateLimit();
        if (rateLimit != null && ArrayUtils.isNotEmpty(rateLimit.event())) {
            builder.event(rateLimit.event()[0]);
        }
        return builder.build();
    }

    public int getCapacity() {
        return Math.max(qps, capacity);
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public int getQps() {
        return qps;
    }

    public void setQps(int qps) {
        this.qps = qps;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public Class<? extends RateAlarmEvent> getEvent() {
        return event;
    }

    public void setEvent(Class<? extends RateAlarmEvent> event) {
        this.event = event;
    }

    public int getInstances() {
        return instances;
    }

    public void setInstances(int instances) {
        this.instances = instances;
    }

    public boolean isDynamic() {
        return dynamic;
    }

    public void setDynamic(boolean dynamic) {
        this.dynamic = dynamic;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static class Builder {
        private String name;
        private int qps;
        private int capacity;
        private int instances;
        private boolean dynamic;
        private boolean enable;
        private Class<? extends RateAlarmEvent> event;

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder qps(int qps) {
            this.qps = qps;
            return this;
        }

        public Builder capacity(int capacity) {
            this.capacity = capacity;
            return this;
        }

        public Builder instances(int instances) {
            this.instances = instances;
            return this;
        }

        public Builder dynamic(boolean dynamic) {
            this.dynamic = dynamic;
            return this;
        }

        public Builder enable(boolean enable) {
            this.enable = enable;
            return this;
        }

        public Builder event(Class<? extends RateAlarmEvent> event) {
            this.event = event;
            return this;
        }

        public LimitCommand build() {
            return new LimitCommand(this);
        }
    }

    private LimitCommand(Builder builder) {
        this.name = builder.name;
        this.qps = builder.qps;
        this.capacity = builder.capacity;
        this.instances = builder.instances;
        this.dynamic = builder.dynamic;
        this.enable = builder.enable;
        this.event = builder.event;
    }
}
